<?php

namespace Thenbsp\Wechat\Payment;

use Thenbsp\Wechat\Util\Util;
use Thenbsp\Wechat\Util\Curl;
use Thenbsp\Wechat\Payment\WXOrder;
use Thenbsp\Wechat\Payment\Business;
use Thenbsp\Wechat\Exception\PaymentException;

class Unifiedorder
{
    /**
     * 统一下单接口
     * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
     */
    const UNIFIEDORDER_URL = 'https://api.mch.weixin.qq.com/pay/unifiedorder';

    /**
     * Curl 网络工具
     */
    protected $curl;

    /**
     * 订单信息
     */
    protected $order;

    /**
     * 商户信息
     */
    protected $business;

    /**
     * 构造方法
     */
    public function __construct(Business $business = null, WXOrder $order = null)
    {
        $this->curl = new Curl;

        if( !is_null($order) ) {
            $this->setOrder($order);
        }

        if( !is_null($business) ) {
            $this->setBusiness($business);
        }
    }

    /**
     * 设置订单
     */
    public function setOrder(WXOrder $order)
    {
        if( !is_null($order) ) {
            try {
                $order->checkParams();
            } catch (Exception $e) {
                throw new PaymentException($e->getMessage());
            }

            if( !$order->hasParams('nonce_str') ) {
                $order->nonce_str(Util::randomString());
            }

            if( !$order->hasParams('spbill_create_ip') ) {
                $order->spbill_create_ip(Util::clientIP());
            }

            if( !$order->hasParams('trade_type') ) {
                if( !$order->hasParams('openid') ) {
                    throw new PaymentException('openid is required');
                }
                $order->trade_type('JSAPI');
            }

            $this->order = $order;
        }
    }

    /**
     * 获取订单
     */
    public function getOrder()
    {
        return $this->order;
    }

    /**
     * 设置商户
     */
    public function setBusiness(Business $business)
    {
        if( !is_null($business) ) {
            try {
                $business->checkParams();
            } catch (Exception $e) {
                throw new PaymentException($e->getMessage());
            }
            $this->business = $business;
        }
    }

    /**
     * 获取商户
     */
    public function getBusiness()
    {
        return $this->business;
    }

    /**
     * 获取统一下单结果
     */
    public function getResponse()
    {
        if( is_null($this->business) ) {
            throw new PaymentException('Business is required');
        }

        if( is_null($this->order) ) {
            throw new PaymentException('Order is required');
        }

        $params = $this->order->getParams();

        $params['appid']    = $this->business->getParams('appid');
        $params['mch_id']   = $this->business->getParams('mch_id');

        ksort($params);

        $sign = http_build_query($params);
        $sign = urldecode($sign).'&key='.$this->business->getParams('mch_key');
        $sign = strtoupper(md5($sign));

        $params['sign'] = $sign;

        $request    = Util::array2XML($params);
        $response   = $this->curl->post(static::UNIFIEDORDER_URL, $request);

        if( empty($response) ) {
            throw new PaymentException(sprintf('Get Unifiedorder Failure: %s',
                $this->curl->error()
            ));
        }



        $object = Util::XML2Array($response);

        if( isset($object['result_code']) &&
            ($object['result_code'] === 'FAIL') ) {
            throw new PaymentException($object['err_code'].': '.$object['err_code_des']);
        }

        if( isset($object['return_code']) &&
            $object['return_code'] === 'FAIL' ) {
            throw new PaymentException($object['return_code'].': '.$object['return_msg']);
        }

        return $object;
    }

}